﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System.Drawing.Drawing2D;

namespace Luckdraw
{
    public partial class Form1 : Form
    {
        AutoAdaptWindowsSize autoAdaptSize;
        string logPath = Application.StartupPath + "\\log.txt";
        public Form1()
        {
            InitializeComponent();
            #region 窗体缩放
            autoAdaptSize = new AutoAdaptWindowsSize(this);
            autoAdaptSize.InitControlsInfo(this.Controls[0]);
            #endregion
        }
        List<name> namelist = new List<name>();
        List<prize> prizelist = new List<prize>();
        List<bingo> bingolist = new List<bingo>();
        List<int> BingoIndexList = new List<int>();
        prize CurrentPrize = new prize();
        int CurrentMaxBingoCount = 0;

        //若要用头像
        List<Rotation> RotationImgList = new List<Rotation>();
        //不用头像
        List<Label> RotationLabelList = new List<Label>();


        //System.Media.SoundPlayer playerstart = new System.Media.SoundPlayer();
        System.Media.SoundPlayer playerbingo = new System.Media.SoundPlayer();
        Mp3Player playerstart = new Mp3Player();

        private void Form1_Load(object sender, EventArgs e)
        {
            //set background image.
            if (File.Exists(Application.StartupPath + "\\background.jpg"))
            {
                Bitmap bm = new Bitmap(Application.StartupPath + "\\background.jpg");
                this.panel5.BackgroundImage = bm;
                this.panel5.BackgroundImageLayout = ImageLayout.Stretch;
            }

            if (File.Exists(Application.StartupPath + "\\button.jpg"))
            {
                Bitmap bm = new Bitmap(Application.StartupPath + "\\button.jpg");
                this.btnBingo.BackgroundImage = bm;
                this.btnNext.BackgroundImage = bm;
                this.btnNext.BackgroundImageLayout = ImageLayout.Stretch;
                this.btnBingo.BackgroundImageLayout = ImageLayout.Stretch;
            }

            this.FormBorderStyle = FormBorderStyle.None;

            this.WindowState = FormWindowState.Maximized;
            //playerstart = new System.Media.SoundPlayer();
            //playerstart.SoundLocation = Application.StartupPath + "\\background.wav";
            //playerstart.Load();
            playerbingo = new System.Media.SoundPlayer();
            playerbingo.SoundLocation = Application.StartupPath + "\\bingo.wav";
            playerbingo.Load();

            playerstart.FilePath = Application.StartupPath + "\\background.mp3";



            lblTitle.BackColor = Color.Transparent;
            panelRotations.BackColor = Color.Transparent;
            lblBingo.BackColor = Color.Transparent;

            panBingo.BackColor = Color.Transparent;
            lblCurrentPrize.BackColor = Color.Transparent;
            //btnBingo.BackColor= Color.Transparent;
            //btnNext.BackColor=Color.Transparent;
            lblCurrnetPrizeDescription.BackColor = Color.Transparent;
            lblCurrentPrizeBigShow.BackColor = Color.Transparent;


            // asc.controllInitializeSize(this);
            //MessageBox.Show("确认退出系统?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

            string ConfigPath = Application.StartupPath + "\\Config.xlsx";
            if (!File.Exists(ConfigPath))
            {
                MessageBox.Show("Conifg info was missing, system cannot work!");
                return;
            }

            try
            {
                XSSFWorkbook workbook = new XSSFWorkbook(ConfigPath);
                namelist = GetNameList(workbook);
                prizelist = GetPrizeList(workbook);
                lblTitle.Text = GetTitle(workbook);

                prizelist = prizelist.OrderBy(x => x.Seq).ToList();

                int allPrizeCount = 0;
                foreach (prize prize in prizelist)
                {
                    allPrizeCount += prize.Count;
                }

                if (allPrizeCount > namelist.Count)
                {
                    //MessageBox.Show("配置有误，参与人数少于奖项人数！");

                    if (MessageBox.Show("配置有误！！！参与人数少于奖项人数，是否继续？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                    {
                        Application.Exit();
                    }
                }

                initCurrentPrize();

            }
            catch (Exception ex)
            {
                WriteLog(ex.Message);
                MessageBox.Show("配置有误，请查看log！");
                Application.Exit();
            }



            //to set middle display


            SetMiddle();

        }


        #region set Control Middle
        private void SetMiddleControl(Control contorl)
        {
            contorl.Left = (this.Width - contorl.Width) / 2;
        }

        private void SetMiddle()
        {
            SetMiddleControl(lblTitle);
            SetMiddleControl(btnBingo);
            SetMiddleControl(btnNext);
            //TODO
            //SetMiddleControl(pictureBox1);
            //SetMiddleControl(lblName);
            SetMiddleControl(lblCurrentPrizeBigShow);
            SetMiddleControl(lblCurrnetPrizeDescription);


        }
        #endregion

        #region get from Config.xlsx
        private string GetTitle(XSSFWorkbook workbook)
        {
            int SheetCount = workbook.NumberOfSheets;//
            int SheetIndex = 2;
            for (int i = 0; i < SheetCount; i++)
            {
                string SheetName = workbook.GetSheetName(i);
                if (SheetName.Contains("title"))
                {
                    SheetIndex = i;
                    break;
                }
            }

            var sheet = workbook.GetSheetAt(SheetIndex);//title
            var Row = sheet.GetRow(0);

            string title = Row.GetCell(0).StringCellValue;



            return title;
        }
        private List<name> GetNameList(XSSFWorkbook workbook)
        {

            int SheetCount = workbook.NumberOfSheets;//
            int SheetIndex = 0;
            for (int i = 0; i < SheetCount; i++)
            {
                string SheetName = workbook.GetSheetName(i);
                if (SheetName.Contains("namelist"))
                {
                    SheetIndex = i;
                    break;
                }
            }

            var sheet = workbook.GetSheetAt(0);//namelist
            int RowCount = sheet.LastRowNum;
            var Row = sheet.GetRow(0);
            int CellCount = Row.LastCellNum;

            int NameIndex = 1;

            for (int i = 0; i < CellCount; i++)
            {
                string str = Row.GetCell(i).StringCellValue;
                if (str != null && str.ToUpper().Trim() == "NAME")
                {
                    NameIndex = i; break;
                }
            }


            List<name> namelist = new List<Luckdraw.name>();

            //存值
            int SN = 0;
            for (int i = 1; i < RowCount + 1; i++)
            {
                name name = new name();

                //var strSN = sheet.GetRow(i).GetCell(SNIndex);
                var strName = sheet.GetRow(i).GetCell(NameIndex);
                if (strName != null)
                {
                    SN++;
                    name.SN = SN;
                    name.Name = strName.ToString();
                }
                namelist.Add(name);

            }

            return namelist;
        }
        private List<prize> GetPrizeList(XSSFWorkbook workbook)
        {
            int SheetCount = workbook.NumberOfSheets;//
            int SheetIndex = 1;
            for (int i = 0; i < SheetCount; i++)
            {
                string SheetName = workbook.GetSheetName(i);
                if (SheetName.Contains("prizelist"))
                {
                    SheetIndex = i;
                    break;
                }
            }

            var sheet = workbook.GetSheetAt(1);//prizelist
            int RowCount = sheet.LastRowNum;
            var Row = sheet.GetRow(0);
            int CellCount = Row.LastCellNum;

            int PrizeNameIndex = 1;
            //int DescriptionIndex = 2;
            //int ImageUrlIndex = 2;
            int CountIndex = 3;
            int SeqIndex = 4;
            int PerTimeIndex = 5;
            int HeadImageIndex = 6;

            for (int i = 0; i < CellCount; i++)
            {
                string str = Row.GetCell(i).StringCellValue;
                if (str != null && str.ToUpper().Trim() == "PRIZENAME")
                    PrizeNameIndex = i;
                // else if (str != null && str.ToUpper().Trim() == "DESCRIPTION")
                //    DescriptionIndex = i;
                // else if (str != null && str.ToUpper().Trim() == "IMAGEURL")
                //    ImageUrlIndex = i;
                else if (str != null && str.ToUpper().Trim() == "HEADIMAGE")
                    HeadImageIndex = i;
                else if (str != null && str.ToUpper().Trim() == "COUNT")
                    CountIndex = i;
                else if (str != null && str.ToUpper().Trim() == "SEQ")
                    SeqIndex = i;
                else if (str != null && str.ToUpper().Trim() == "PERTIME")
                    PerTimeIndex = i;

            }


            List<prize> modellist = new List<Luckdraw.prize>();

            //存值
            int SN = 0;
            for (int i = 1; i < RowCount + 1; i++)
            {
                prize model = new prize();

                var strPrizeName = sheet.GetRow(i).GetCell(PrizeNameIndex);
                //var strDescription = sheet.GetRow(i).GetCell(DescriptionIndex);
                //var strImageUrl = sheet.GetRow(i).GetCell(ImageUrlIndex);
                var strCount = sheet.GetRow(i).GetCell(CountIndex);
                var strSeq = sheet.GetRow(i).GetCell(SeqIndex);
                var strPerTime = sheet.GetRow(i).GetCell(PerTimeIndex);
                var strHeadImage = sheet.GetRow(i).GetCell(HeadImageIndex); 
                if (strCount != null && strSeq != null)
                {
                    SN++;
                    model.SN = SN;
                    model.PrizeName = strPrizeName == null ? "" : strPrizeName.ToString();
                    //model.Description = strDescription == null ? "" : strDescription.ToString();
                    //model.ImageUrl = strImageUrl == null ? "" : strImageUrl.ToString();
                    model.Count = int.Parse(strCount.ToString());
                    model.Seq = int.Parse(strSeq.ToString());
                    model.PerTime = int.Parse(strPerTime.ToString());
                    model.HeadImage = ((strHeadImage == null ? "" : strHeadImage.ToString().ToUpper()) == "Y" ? true : false);
                    if (model.HeadImage && model.PerTime > 10)
                        model.PerTime = 10;
                    else if( model.PerTime > 20)
                        model.PerTime = 20;
                }
                modellist.Add(model);

            }

            return modellist;
        }
        #endregion


        private void initGroupRotation()
        {
            RotationImgList.Clear();
            RotationLabelList.Clear();
            this.panelRotations.Controls.Clear();



            int PerTime = CurrentPrize.PerTime > CurrentMaxBingoCount ? CurrentMaxBingoCount : CurrentPrize.PerTime;

            //this.panelRotations.Location.X
            int totalwidth = 555;
            int totalheight = 264;

            if (CurrentPrize.HeadImage)
            {
                int rows = PerTime / 5;
                if (PerTime % 5 > 0) rows += 1;
                int columns = PerTime > 5 ? 5 : PerTime;
                int currentrow = 0;

                for (int i = 0; i < PerTime; i++)
                {
                    Rotation rotation = new Rotation();
                    // rotation.Width = 140;
                    if (columns >= 4)
                    {
                        rotation.Width = totalwidth / (columns + 1);
                        rotation.Height = totalheight / (rows + 1);
                    }

                    // rotation.Height = 140;
                    int x = (totalwidth - columns * rotation.Width) / (columns + 1) * (i % 5 + 1) + (i % 5 * rotation.Width);
                    int y = (totalheight - rows * rotation.Height) / (rows + 1) * (currentrow + 1) + (currentrow * rotation.Height);

                    Point rotationLocatoin = new Point(x, y);
                    rotation.Location = rotationLocatoin;
                    //rotation.Initial();
                    RotationImgList.Add(rotation);
                    this.panelRotations.Controls.Add(rotation);

                    if (i != 0 && (i + 1) % 5 == 0)
                    {
                        currentrow++;//each row have max 5 pictures.
                    }
                }
            }
            else
            {
                int rows = PerTime / 5;
                if (PerTime % 5 > 0) rows += 1;
                int columns = PerTime > 5 ? 5 : PerTime;
                int currentrow = 0;

                for (int i = 0; i < PerTime; i++)
                {
                    Label rotation = new Label();
                    rotation.ForeColor = Color.Yellow;
                    rotation.TextAlign =ContentAlignment.MiddleCenter;

                    rotation.Width = totalwidth / (columns + 1);
                    rotation.Height = totalheight / (rows + 1);
                    if (columns >= 4)
                    {
                        rotation.Font = new Font(rotation.Font.FontFamily, 20, FontStyle.Bold);
                    }
                    else
                    {
                        rotation.Font = new Font(rotation.Font.FontFamily, 35, FontStyle.Bold);
                    }

                    // rotation.Height = 140;
                    int x = (totalwidth - columns * rotation.Width) / (columns + 1) * (i % 5 + 1) + (i % 5 * rotation.Width)+120;
                    int y = (totalheight - rows * rotation.Height) / (rows + 1) * (currentrow + 1) + (currentrow * rotation.Height)+50;

                    Point rotationLocatoin = new Point(x, y);
                    rotation.Location = rotationLocatoin;
                    //rotation.Initial();
                    RotationLabelList.Add(rotation);
                    this.panelRotations.Controls.Add(rotation);

                    if (i != 0 && (i + 1) % 5 == 0)
                    {
                        currentrow++;//each row have max 5 pictures.
                    }
                }
            }



        }

        private void initCurrentPrize()
        {
            if (prizelist.Count > 0)
            {
                CurrentPrize = prizelist[0];
                CurrentMaxBingoCount = CurrentPrize.Count;
                lblCurrnetPrizeDescription.Text = "共计" + CurrentPrize.Count + "名额";
                lblCurrentPrize.Text = "点击开始抽取";
                btnBingo.Text = "开始";
                btnBingo.Visible = true;
                btnNext.Visible = false;


                //TODO
                WriteLog("准备抽取：" + CurrentPrize.PrizeName + " 共计" + CurrentPrize.Count + "名额");

                panelRotations.Controls.Clear();
                lblBingo.Text = "";
                lblCurrentPrizeBigShow.Text = CurrentPrize.PrizeName;
                lblCurrentPrizeBigShow.Visible = true;
                lblCurrnetPrizeDescription.Visible = true;
                lblCurrentPrize.Visible = false;
                lblBingo.Visible = false;
                SetMiddle();
            }
            else
            {
                btnBingo.Visible = false;
                btnNext.Visible = false;

                lblCurrnetPrizeDescription.Visible = false;

                panelRotations.Controls.Clear();


                lblBingo.Visible = false;
                lblCurrentPrize.Visible = false;
                lblCurrentPrizeBigShow.Visible = true;
                lblCurrentPrizeBigShow.Text = "抽奖结束！";
                lblCurrentPrize.Text = "所有奖项已抽完";

            }

            SetMiddle();
        }



        private void timer1_Tick(object sender, EventArgs e)
        {
            BingoIndexList.Clear();

            int length = namelist.Count;


            int PerTime = CurrentPrize.PerTime > CurrentMaxBingoCount ? CurrentMaxBingoCount : CurrentPrize.PerTime;

            if (CurrentPrize.HeadImage)
            {
                foreach (Rotation rotation in RotationImgList)
                {
                    var Seed = Guid.NewGuid().GetHashCode();
                    Random r = new Random(Seed);
                    int index = r.Next(0, length);
                    while (BingoIndexList.Contains(index))
                    {
                        Seed = Guid.NewGuid().GetHashCode();
                        r = new Random(Seed);
                        index = r.Next(0, length);
                    }
                    rotation.SetNameInfo(namelist[index]);
                    //TODO                
                    //SetMiddleControl(lblName);
                    BingoIndexList.Add(index);
                }
            }
            else
            {
                foreach (Label rotation in RotationLabelList)
                {
                    var Seed = Guid.NewGuid().GetHashCode();
                    Random r = new Random(Seed);
                    int index = r.Next(0, length);
                    while (BingoIndexList.Contains(index))
                    {
                        Seed = Guid.NewGuid().GetHashCode();
                        r = new Random(Seed);
                        index = r.Next(0, length);
                    }
                    rotation.Text=namelist[index].Name;
                    //TODO                
                    //SetMiddleControl(lblName);
                    BingoIndexList.Add(index);
                }
            }

        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                btnBingo.Enabled = false;
                if (CurrentMaxBingoCount <= 0)
                {
                    MessageBox.Show(CurrentPrize.PrizeName + "已经抽取完毕！！！");
                    btnBingo.Visible = false;
                    btnNext.Visible = true;
                    return;
                }
                if (namelist.Count == 0)
                {
                    //TODO
                    //string headimage = Application.StartupPath + @"\HeadImages\guest.jpg";
                    //this.pictureBox1.Image = Image.FromFile(headimage);
                    //lblName.Text = "没有候选人";
                    //pictureBox1.BorderStyle = BorderStyle.None;
                    //pictureBox1.Image = null;
                    timer1.Stop();
                    SetMiddle();
                    MessageBox.Show("所有人已中奖，没有候选人！！！");

                    return;

                }
                if (btnBingo.Text == "开始")
                {
                    lblCurrentPrizeBigShow.Visible = false;
                    lblCurrnetPrizeDescription.Visible = false;
                    lblCurrentPrize.Visible = true;
                    lblBingo.Visible = true;

                    if (CurrentMaxBingoCount > 1 && CurrentPrize.PerTime > 1)
                    {
                        int tempIndex = (CurrentPrize.Count - CurrentMaxBingoCount + 1);
                        string message = "第 " + tempIndex.ToString() + "至" + (tempIndex + CurrentPrize.PerTime - 1) + " 个";
                        lblCurrentPrize.Text = "正在抽取" + message + CurrentPrize.PrizeName + "...";
                    }
                    else
                    {
                        lblCurrentPrize.Text = "正在抽取第 " + (CurrentPrize.Count - CurrentMaxBingoCount + 1).ToString() + " 个" + CurrentPrize.PrizeName + "...";
                    }                   

                    playerstart.Play();

                    btnBingo.Text = "抽奖";
                    initGroupRotation();
                    timer1.Start();
                    //TODO
                    //pictureBox1.BorderStyle = BorderStyle.FixedSingle;
                    //pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
                    //pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;




                }
                else if (btnBingo.Text == "继续")
                {
                    if (CurrentMaxBingoCount > 1 && CurrentPrize.PerTime>1)
                    {
                        int tempIndex = (CurrentPrize.Count - CurrentMaxBingoCount + 1);
                        string message = "第 " + tempIndex.ToString() + "至" + (tempIndex + CurrentPrize.PerTime - 1) + " 个";
                        lblCurrentPrize.Text = "正在抽取" + message + CurrentPrize.PrizeName + "...";
                    }
                    else
                    {
                        lblCurrentPrize.Text = "正在抽取第 " + (CurrentPrize.Count - CurrentMaxBingoCount + 1).ToString() + " 个" + CurrentPrize.PrizeName + "...";
                    }


                    playerbingo.Stop();

                    if (CurrentMaxBingoCount == CurrentPrize.Count)
                        playerstart.Play();

                    else
                        playerstart.Continue();


                    btnBingo.Text = "抽奖";
                    if (CurrentMaxBingoCount < CurrentPrize.PerTime)
                        initGroupRotation();
                    timer1.Start();
                }
                else
                {
                    btnBingo.Text = "继续";
                    playerstart.Pause();
                    playerbingo.Play();

                    timer1.Stop();


                    foreach (int BingoIndex in BingoIndexList)
                    {
                        bingo bingo = new Luckdraw.bingo();
                        bingo.Name = namelist[BingoIndex].Name;
                        bingo.PrizeName = CurrentPrize.PrizeName;
                        bingolist.Add(bingo);
                        CurrentMaxBingoCount--;
                        int bingoCount = CurrentPrize.Count - CurrentMaxBingoCount;


                        lblBingo.Text += @"
" + bingoCount.ToString() + "." + bingo.Name + " " + bingo.PrizeName;//+ lblBingo.Text
                        panBingo.VerticalScroll.Value = panBingo.VerticalScroll.Maximum;

                        WriteLog(bingoCount.ToString() + "." + bingo.Name + " " + bingo.PrizeName);


                    }
                    BingoIndexList.Sort((x, y) => -x.CompareTo(y));
                    foreach (int BingoIndex in BingoIndexList)
                    {
                        namelist.RemoveAt(BingoIndex);
                    }
                    //lblCurrentPrize.Text = "已抽取" + (CurrentPrize.Count - CurrentMaxBingoCount).ToString() + "个";
                    if (CurrentMaxBingoCount > 0)
                        lblCurrentPrize.Text = "还有" + CurrentMaxBingoCount.ToString() + "名额";
                    else
                        lblCurrentPrize.Text = "";

                    if (CurrentMaxBingoCount <= 0)
                    {
                        btnBingo.Visible = false;
                        btnNext.Visible = true;
                        return;
                    }

                }
            }
            finally
            {
                btnBingo.Enabled = true;
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {

            if (prizelist.Count > 0)
            {
                prizelist.RemoveAt(0);
                initCurrentPrize();
            }
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (autoAdaptSize != null)
            {
                try
                {
                    autoAdaptSize.FormSizeChanged();
                    SetMiddle();

                }
                catch { }
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //playerstart.Dispose();
            //playerbingo.Dispose();

            if (bingolist.Count > 0)
            {

                var workbook = new XSSFWorkbook();
                var sheet = workbook.CreateSheet("bingolist");
                var headerRow = sheet.CreateRow(0);
                headerRow.CreateCell(0).SetCellValue("Name");//used
                headerRow.CreateCell(1).SetCellValue("PrizeName");//used
                sheet.CreateFreezePane(0, 1, 0, 1);
                int rowNumber = 1;

                foreach (bingo bingo in bingolist)
                {
                    var row = sheet.CreateRow(rowNumber++);
                    row.CreateCell(0).SetCellValue(bingo.Name);
                    row.CreateCell(1).SetCellValue(bingo.PrizeName);
                }
                string fileName = Application.StartupPath + "\\bingolist" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx";

                FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                workbook.Write(fs); //写入到excel
                fs.Close();
                fs.Dispose();
            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (bingolist.Count > 0)
            {
                if (MessageBox.Show("确认退出系统？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                {
                    e.Cancel = true;
                }
                else if (prizelist.Count > 0)
                {
                    if (MessageBox.Show("退出系统无法继续抽奖，继续退出？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                    {
                        e.Cancel = true;
                    }
                }
            }

        }


        private void WriteLog(string log)
        {
            DirectoryInfo di = new DirectoryInfo(logPath.Substring(0, logPath.LastIndexOf("\\")));
            if (!di.Exists)
            {
                di.Create();
            }

            StreamWriter sw = new StreamWriter(logPath, true);
            sw.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "] " + log);
            sw.Close();
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "] " + log);
        }

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            //if (e.KeyChar == (char)Keys.Space)
            //{
            //    button3_Click(null,null);
            //}
            //else if (e.KeyChar == (char)Keys.Escape)
            //{
            //    Application.Exit();
            //}

        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 32)
            {
                button3_Click(null, null);
            }
            else if (e.KeyValue == 27)
            {
                Application.Exit();
            }

        }

        private void groupRotations_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
